<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js coal">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>react life cycle - Andrew&#x27;s Blog</title>


        <!-- Custom HTML head -->
        
        <meta name="description" content="Andrew Ryan&#x27;s Blog">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        <link rel="stylesheet" href="../../src/style/custom.css">

        <!-- MathJax -->
        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    </head>
    <body>
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('coal')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var html = document.querySelector('html');
            var sidebar = null;
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> Linux</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/Linux/git_cheatsheet.html"><strong aria-hidden="true">1.6.</strong> Git Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/Linux/bash_cheatsheet.html"><strong aria-hidden="true">1.7.</strong> Bash Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/macos/mac.html"><strong aria-hidden="true">2.</strong> MacOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/macos/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li><li class="chapter-item "><a href="../../posts/macos/macos_pwn_env_setup.html"><strong aria-hidden="true">2.2.</strong> macos pwn env setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> Swift</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in Swift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> iOS</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> Objective-C</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> Dart</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> Rust</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item "><a href="../../posts/rust/compress_rust_binary_size.html"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/how_to_create_yolov8_based_object_detection_web_service_using_python,_julia,_node.js,_javascript,_go_and_rust.html"><strong aria-hidden="true">7.25.</strong> How to create YOLOv8-based object detection web service using Python, Julia, Node.js, JavaScript, Go and Rust</a></li><li class="chapter-item "><a href="../../posts/rust/implment_builder_proc_macro_for_command_struct.html"><strong aria-hidden="true">7.26.</strong> implment Builder proc-macro for Command struct</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> Java</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> Python</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li><li class="chapter-item "><a href="../../posts/python/sanctum_model_yaml.html"><strong aria-hidden="true">9.5.</strong> sanctum model yaml</a></li><li class="chapter-item "><a href="../../posts/python/how_to_detect_objects_on_images_using_the_yolov8_neural_network.html"><strong aria-hidden="true">9.6.</strong> How to detect objects on images using the YOLOv8 neural network</a></li><li class="chapter-item "><a href="../../posts/python/use_huggingface_model.html"><strong aria-hidden="true">9.7.</strong> use huggingface model</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> Go</a></li><li class="chapter-item "><a href="../../posts/javascript/js.html"><strong aria-hidden="true">11.</strong> Javascript</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/javascript/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/javascript/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/javascript/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/javascript/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/javascript/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/javascript/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/javascript/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/javascript/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/javascript/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> Ruby</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item "><a href="../../posts/ruby/learn_ruby.html"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item "><a href="../../posts/ruby/ruby_note.html"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> React</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../posts/react/react_life_cycle.html" class="active"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> Vue</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> Angular</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> Css</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> Php</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.</strong> Windows</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/windows/windows.html"><strong aria-hidden="true">18.1.</strong> Windows</a></li><li class="chapter-item "><a href="../../posts/windows/windows10_use_powershell_dedup_redundent_path.html"><strong aria-hidden="true">18.2.</strong> Windows10 use PowerShell dedup redundent PATH</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">19.</strong> Leetcode</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">19.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">19.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">19.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">19.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">19.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">19.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">19.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">19.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">20.</strong> CTF</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">20.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">20.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">20.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">20.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">20.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">20.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">20.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">20.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">20.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">20.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">20.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">20.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">20.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">20.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">20.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">20.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">20.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">20.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">20.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">20.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">20.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">20.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">20.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">20.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">20.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/zip_plain_text_attack.html"><strong aria-hidden="true">20.26.</strong> Zip plain text attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">20.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_patch_defense_skill.html"><strong aria-hidden="true">20.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">20.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">20.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">20.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">20.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">20.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">20.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">20.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">20.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/pwnable_kr_challenge.html"><strong aria-hidden="true">20.37.</strong> Solutions for pwnable.kr</a></li><li class="chapter-item "><a href="../../posts/ctf/the_periodic_table.html"><strong aria-hidden="true">20.38.</strong> The Periodic Table</a></li><li class="chapter-item "><a href="../../posts/ctf/pwntools_cheatsheet.html"><strong aria-hidden="true">20.39.</strong> Pwntools Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/gdb_cheatsheet.html"><strong aria-hidden="true">20.40.</strong> GDB Cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/iltes/iltes.html"><strong aria-hidden="true">21.</strong> ILTES</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/iltes/iltes_writing.html"><strong aria-hidden="true">21.1.</strong> ILTES Writing</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <!-- Track and set sidebar scroll position -->
        <script>
            var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
            sidebarScrollbox.addEventListener('click', function(e) {
                if (e.target.tagName === 'A') {
                    sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
                }
            }, { passive: true });
            var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
            sessionStorage.removeItem('sidebar-scroll');
            if (sidebarScrollTop) {
                // preserve sidebar scroll position when navigating via links within sidebar
                sidebarScrollbox.scrollTop = sidebarScrollTop;
            } else {
                // scroll sidebar to current active section when navigating via "next/previous chapter" buttons
                var activeSection = document.querySelector('#sidebar .active');
                if (activeSection) {
                    activeSection.scrollIntoView({ block: 'center' });
                }
            }
        </script>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Andrew&#x27;s Blog</h1>

                    <div class="right-buttons">
                        <a href="https://gitee.com/dnrops/dnrops" title="Git repository" aria-label="Git repository">
                            <i id="git-repository-button" class="fa fa-github"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="rect-组件的生命周期"><a class="header" href="#rect-组件的生命周期">rect 组件的生命周期</a></h1>
<p>在组件创建、到加载到页面上运行、以及组件被销毁的过程中，总是伴随着各种各样的事件，这些在组件特定时期，触发的事件统称为组件的生命周期。</p>
<h2 id="生命周期的阶段"><a class="header" href="#生命周期的阶段">生命周期的阶段</a></h2>
<p>组件生命周期分为三个阶段，下面分别来讲解。</p>
<h3 id="1组件创建阶段"><a class="header" href="#1组件创建阶段">1、组件创建阶段</a></h3>
<blockquote>
<p>组件创建阶段的生命周期函数，有一个显著的特点：创建阶段的生命周期函数，在组件的一辈子中，只执行一次。</p>
</blockquote>
<ul>
<li>getDefaultProps</li>
</ul>
<p>初始化 props 属性默认值。</p>
<ul>
<li>getInitialState</li>
</ul>
<p>初始化组件的私有数据。因为 state 是定义在组件的 constructor 构造器当中的，只要 new 了 class 类，必然会调用
constructor 构造器。</p>
<ul>
<li>componentWillMount()</li>
</ul>
<p>组件将要被挂载。此时还没有开始渲染虚拟 DOM。</p>
<p>在这个阶段，不能去操作 DOM 元素，但可以操作属性、状态、function。相当于 Vue 中的 Create()函数。</p>
<ul>
<li>render()</li>
</ul>
<p>第一次开始渲染真正的虚拟 DOM。当 render 执行完，内存中就有了完整的虚拟 DOM 了。</p>
<p>意思是，此时，虚拟 DOM 在内存中创建好了，但是还没有挂在到页面上。</p>
<p>在这个函数内部，不能去操作 DOM 元素，<strong>因为还没 return 之前，虚拟 DOM 还没有创建</strong>；当 return 执行完毕后，虚拟 DOM
就创建好了，但是还没有挂在到页面上。</p>
<ul>
<li><strong>componentDidMount()</strong></li>
</ul>
<p><strong>当组件（虚拟 DOM）挂载到页面之后，会进入这个生命周期函数</strong>。</p>
<p>只要进入到这个生命周期函数，则必然说明，页面上已经有可见的 DOM 元素了。此时，组件已经显示到了页面上，state 上的数据、内存中的虚拟
DOM、以及浏览器中的页面，已经完全保持一致了。</p>
<p>当这个方法执行完，组件就进入都了 运行中 的状态。所以说，componentDidMount 是创建阶段的最后一个函数。</p>
<p>在这个函数中，我们可以放心的去 操作 页面上你需要使用的 DOM 元素了。如果我们想操作 DOM 元素，最早只能在 componentDidMount
中进行。相当于 Vue 中的 mounted() 函数</p>
<h3 id="2组件运行阶段"><a class="header" href="#2组件运行阶段">2、组件运行阶段</a></h3>
<blockquote>
<p>有一个显著的特点，根据组件的 state 和 props 的改变，有选择性的触发 0 次或多次。</p>
</blockquote>
<ul>
<li>componentWillReceiveProps()</li>
</ul>
<p>组件将要接收新属性。只有当父组件中，通过某些事件，重新修改了 传递给 子组件的 props 数据之后，才会触发这个钩子函数。</p>
<ul>
<li>shouldComponentUpdate()</li>
</ul>
<p>判断组件是否需要被更新。此时，组件尚未被更新，但是，state 和 props 肯定是最新的。</p>
<ul>
<li>componentWillUpdate()</li>
</ul>
<p>组件将要被更新。此时，组件还没有被更新，在进入到这个生命周期函数的时候，内存中的虚拟 DOM 还是旧的，页面上的 DOM
元素也是旧的。（也就是说，此时操作的是旧的 DOM 元素）</p>
<ul>
<li>render</li>
</ul>
<p>此时，又要根据最新的 state 和 props，重新渲染一棵内存中的 虚拟 DOM 树。当 render 调用完毕，内存中的旧 DOM 树，已经被新 DOM
树替换了！此时，虚拟 DOM 树已经和组件的 state 保持一致了，都是最新的；但是页面还是旧的。</p>
<ul>
<li>componentDidUpdate</li>
</ul>
<p>此时，组件完成更新，页面被重新渲染。此时，state、虚拟 DOM 和 页面已经完全保持同步。</p>
<h3 id="3组件销毁阶段"><a class="header" href="#3组件销毁阶段">3、组件销毁阶段</a></h3>
<p>一辈子只执行一次。</p>
<ul>
<li>componentWillUnmount: 组件将要被卸载。此时组件还可以正常使用。</li>
</ul>
<p>React 生命周期的截图如下：</p>
<p>20190212_1745.jpg</p>
<p>生命周期对比：</p>
<ul>
<li>
<p><a href="https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA">vue 中的生命周期图</a></p>
</li>
<li>
<p><a href="http://www.race604.com/react-native-component-lifecycle/">React Native 中组件的生命周期</a></p>
</li>
</ul>
<h2 id="组件生命周期的执行顺序"><a class="header" href="#组件生命周期的执行顺序">组件生命周期的执行顺序</a></h2>
<p><strong>1、Mounting</strong>：</p>
<ul>
<li>
<p>constructor()</p>
</li>
<li>
<p>componentWillMount()</p>
</li>
<li>
<p>render()</p>
</li>
<li>
<p>componentDidMount()</p>
</li>
</ul>
<p><strong>2、Updating</strong>：</p>
<ul>
<li>
<p>componentWillReceiveProps(nextProps)：接收父组件传递过来的属性</p>
</li>
<li>
<p>shouldComponentUpdate(nextProps, nextState)：一旦调用 setState，就会触发这个方法。方法默认 return
true；如果 return false，后续的方法就不会走了。</p>
</li>
<li>
<p>componentWillUpdate(nextProps, nextState)</p>
</li>
<li>
<p>render()</p>
</li>
<li>
<p>componentDidUpdate(prevProps, prevState)</p>
</li>
</ul>
<p><strong>3、Unmounting</strong>：</p>
<ul>
<li>componentWillUnmount()</li>
</ul>
<h2 id="defaultprops-和-prop-types"><a class="header" href="#defaultprops-和-prop-types">defaultProps 和 prop-types</a></h2>
<h3 id="使用-defaultprops-设置组件的默认值"><a class="header" href="#使用-defaultprops-设置组件的默认值">使用 defaultProps 设置组件的默认值</a></h3>
<p>React 中，使用静态的 <code>defaultProps</code> 属性，来设置组件的默认属性值。</p>
<p>格式举例：</p>
<pre><code class="language-javascript">// 在 React 中，使用静态的 defaultProps 属性，来设置组件的默认属性值
static defaultProps = {
  initcount: 0 // 如果外界没有传递 initcount，那么，自己初始化一个数值（比如0）
};
</code></pre>
<h3 id="使用-prop-types-进行-props-数据类型的校验"><a class="header" href="#使用-prop-types-进行-props-数据类型的校验">使用 prop-types 进行 props 数据类型的校验</a></h3>
<p>在组件中，可以通过 <code>prop-types</code> 把外界传递过来的属性，做类型校验。如果类型不匹配，控制台会弹出告警。</p>
<p>注意：如果要为 传递过来的属性做类型校验，必须安装 React 提供的 第三方包，叫做 <code>prop-types</code>。</p>
<p>格式举例：</p>
<pre><code class="language-javascript">static propTypes = {
  initcount: ReactTypes.number // 使用 prop-types 包，来定义 initcount 为 number 类型
};
</code></pre>
<p>下方代码中，在引用组件的时候，如果类型不匹配：</p>
<pre><code class="language-javascript">// 使用 render 函数渲染 虚拟DOM
ReactDOM.render(
  &lt;div&gt;
    {/* 规定，每个用户在使用 组件的时候，必须传递一个 默认的 数值，作为 组件初始化的 数据 */}
    &lt;Counter initcount=&quot;我是string类型&quot;&gt;&lt;/Counter&gt;
  &lt;/div&gt;,
  document.getElementById(&quot;app&quot;),
);
</code></pre>
<p>控制台告警如下：</p>
<p>20190212_2130.png</p>
<h3 id="代码举例"><a class="header" href="#代码举例">代码举例</a></h3>
<p>我们把 <code>defaultProps</code> 和 <code>prop-types</code> 来举个例子。</p>
<p>（1）index.html:</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;!-- 容器，通过 React 渲染得到的 虚拟DOM，会呈现到这个位置 --&gt;
    &lt;div id=&quot;app&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>（2）main.js:</p>
<pre><code class="language-js">// JS打包入口文件
// 1. 导入包
import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom&quot;;

// 导入计数器组件
import Counter from &quot;./components/Counter.jsx&quot;;

// 使用 render 函数渲染 虚拟DOM
ReactDOM.render(
  &lt;div&gt;
    {/* 规定，每个用户在使用 组件的时候，必须传递一个 默认的 数值，作为 组件初始化的 数据 */}
    &lt;Counter initcount={0}&gt;&lt;/Counter&gt;
  &lt;/div&gt;,
  document.getElementById(&quot;app&quot;),
);
</code></pre>
<p>（3）/components/Counter.jsx：</p>
<pre><code class="language-javascript">import React from &quot;react&quot;;
// 注意： prop-types 包中职能跟单一，只提供了 一些常见的 数据类型，用于做类型校验
import ReactTypes from &quot;prop-types&quot;;

export default class Counter extends React.Component {
  constructor(props) {
    super(props);

    // 初始化组件，保存的是组件的私有数据
    this.state = {
      msg: &quot;ok&quot;,
      count: props.initcount, // 把 父组件传递过来的 initcount 赋值给子组件 state 中的 count值。这样的话，就把 count 值改成了可读可写的 state 属性。因此，以后就能实现“点击 按钮 ，count 值 + 1”的需求了
    };
  }

  // 在 React 中，使用静态的 defaultProps 属性，来设置组件的默认属性值
  static defaultProps = {
    initcount: 0, // 如果外界没有传递 initcount，那么，自己初始化一个 数值，为0
  };

  render() {
    return (
      &lt;div&gt;
        &lt;div&gt;
          &lt;h3&gt;这是 Counter 计数器组件&lt;/h3&gt;
          &lt;p&gt;当前的计数是：{this.state.count}&lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
    // 当 return 执行完毕后， 虚拟DOM创建好了，但是，还没有挂载到真正的页面中
  }
}
</code></pre>
<p>运行效果：</p>
<p>20190212_2100.png</p>
<h2 id="事件绑定"><a class="header" href="#事件绑定">事件绑定</a></h2>
<p>案例：点击按钮后，计数器 +1。</p>
<h3 id="原生-js-做事件绑定"><a class="header" href="#原生-js-做事件绑定">原生 js 做事件绑定</a></h3>
<p>代码举例：</p>
<p>（1）index.html:</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;!-- 容器，通过 React 渲染得到的 虚拟DOM，会呈现到这个位置 --&gt;
    &lt;div id=&quot;app&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>（2）main.js:</p>
<pre><code class="language-js">// JS打包入口文件
// 1. 导入包
import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom&quot;;

// 导入计数器组件
import Counter from &quot;./components/Counter.jsx&quot;;

// 使用 render 函数渲染 虚拟DOM
ReactDOM.render(
  &lt;div&gt;
    {/* 规定，每个用户在使用 组件的时候，必须传递一个 默认的 数值，作为 组件初始化的 数据 */}
    &lt;Counter initcount={0}&gt;&lt;/Counter&gt;
  &lt;/div&gt;,
  document.getElementById(&quot;app&quot;),
);
</code></pre>
<p>（3）/components/Counter.jsx：</p>
<pre><code class="language-java">import React from &quot;react&quot;;
// 注意： prop-types 包的职能跟单一，只提供了 一些常见的 数据类型，用于做类型校验
import ReactTypes from &quot;prop-types&quot;;

export default class Counter extends React.Component {
  constructor(props) {
    super(props);

    // 初始化组件，保存的是组件的私有数据
    this.state = {
      msg: &quot;ok&quot;,
      count: props.initcount // 把 父组件传递过来的 initcount 赋值给子组件 state 中的 count值。这样的话，就把 count 值改成了可读可写的 state 属性。因此，以后就能实现“点击 按钮 ，count 值 + 1”的需求了
    };
  }

  // 在 React 中，使用静态的 defaultProps 属性，来设置组件的默认属性值
  static defaultProps = {
    initcount: 0 // 如果外界没有传递 initcount，那么，自己初始化一个数值（比如0）
  };

  // 这是创建一个 静态的 propTypes 对象，在这个对象中，可以把 外界传递过来的属性，做类型校验
  static propTypes = {
    initcount: ReactTypes.number // 使用 prop-types 包，来定义 initcount 为 number 类型
  };

  render() {
    return (
      &lt;div&gt;
        &lt;div&gt;
          &lt;h3&gt;这是 Counter 计数器组件 &lt;/h3&gt;
          &lt;input type=&quot;button&quot; value=&quot;+1&quot; id=&quot;btn&quot; /&gt;
          &lt;p&gt;当前的计数是：{this.state.count}&lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
    // 当 return 执行完毕后， 虚拟DOM创建好了，但是，还没有挂载到真正的页面中
  }

  // 当组件挂载到页面上之后，会进入这个生命周期函数，只要进入这个生命周期函数了，必然说明，页面上，已经有可见的DOM元素了
  componentDidMount() {
    // 在这个函数中，我们可以放心的去 操作 页面上你需要使用的 DOM 元素了。
    // 也就是说，如果我们想操作DOM元素，最早，只能在 componentDidMount 中进行。
    document.getElementById(&quot;btn&quot;).onclick = () =&gt; {
      this.setState({
        count: this.state.count + 1
      });
    };
  }
}
</code></pre>
<h3 id="使用-react-提供的方法做事件绑定"><a class="header" href="#使用-react-提供的方法做事件绑定">使用 React 提供的方法，做事件绑定</a></h3>
<p>代码举例：</p>
<p>（1）index.html 和 （2）main.js 的代码不变，和上一小段中的代码一致。</p>
<p>（3）/components/Counter.jsx：</p>
<pre><code class="language-java">import React from &quot;react&quot;;
// 注意： prop-types 包的职能跟单一，只提供了 一些常见的 数据类型，用于做类型校验
import ReactTypes from &quot;prop-types&quot;;

export default class Counter extends React.Component {
  constructor(props) {
    super(props);

    // 初始化组件，保存的是组件的私有数据
    this.state = {
      msg: &quot;ok&quot;,
      count: props.initcount // 把 父组件传递过来的 initcount 赋值给子组件 state 中的 count值。这样的话，就把 count 值改成了可读可写的 state 属性。因此，以后就能实现“点击 按钮 ，count 值 + 1”的需求了
    };
  }

  // 在 React 中，使用静态的 defaultProps 属性，来设置组件的默认属性值
  static defaultProps = {
    initcount: 0 // 如果外界没有传递 initcount，那么，自己初始化一个数值（比如0）
  };

  // 这是创建一个 静态的 propTypes 对象，在这个对象中，可以把 外界传递过来的属性，做类型校验
  static propTypes = {
    initcount: ReactTypes.number // 使用 prop-types 包，来定义 initcount 为 number 类型
  };

  render() {
    return (
      &lt;div&gt;
        &lt;div&gt;
          &lt;h3&gt;这是 Counter 计数器组件 &lt;/h3&gt;
          {/* 这里的 this 指向的是 Counter 组件的实例  */}
          &lt;input type=&quot;button&quot; value=&quot;+1&quot; id=&quot;btn&quot; onClick={this.myMethod} /&gt;
          &lt;p&gt;当前的计数是：{this.state.count}&lt;/p&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
    // 当 return 执行完毕后， 虚拟DOM创建好了，但是，还没有挂载到真正的页面中
  }

  // 点击事件的方法定义
  myMethod = () =&gt; {
    // 修改组件的state里面的值
    this.setState({
      count: this.state.count + 1
    });
  };
}
</code></pre>
<h2 id="生命周期函数shouldcomponentupdate"><a class="header" href="#生命周期函数shouldcomponentupdate">生命周期函数：shouldComponentUpdate()</a></h2>
<p>在 shouldComponentUpdate() 函数中，必须要求返回一个<strong>布尔值</strong>。</p>
<p><strong>需要注意的是</strong>：如果返回的值是 false，则不会继续执行后续的生命周期函数，而是直接退回到了 运行中 的状态。因为此时，<strong>后续的 render
函数并没有被调用</strong>，因此页面不会被更新，但是组件的 state 状态，却被修改了。这种情况，我们也可以这样理解：如果返回值为 false，此时只是更新了
state 里面的数值，但是并没有渲染到 DOM 节点上。</p>
<p>利用上面这个特性，我们可以来举个例子。</p>
<p><strong>举例</strong>：实现 Counter 计数器只在偶数情况下更新。</p>
<p>实现思路：在 shouldComponentUpdate() 函数中，如果 state 中 的 count 的值为奇数，就 return false；否则就
return true。</p>
<p>代码实现：（我们在上面的<code>Counter.jsx</code>代码基础之上，做添加）</p>
<pre><code class="language-javascript">  // 判断组件是否需要更新
  shouldComponentUpdate(nextProps, nextState) {

    // 经过打印测试发现：在 shouldComponentUpdate 中，通过 this.state.count 拿到的值，是上一次的旧数据，并不是当前最新的；
    // 解决办法：通过 shouldComponentUpdate 函数的第二个参数 nextState，可以拿到 最新的 state 数据。

    console.log(this.state.count + &quot; ---- &quot; + nextState.count);

    // 需求： 如果 state 中的 count 值是偶数，则 更新页面；如果 count 值 是奇数，则不更新页面。最终实现的的页面效果：2，4，6，8，10，12....
    // return this.state.count % 2 === 0 ? true : false
    return nextState.count % 2 === 0 ? true : false;
  }
</code></pre>
<p>上面这部分的代码，和 render() 方法是并列的。我们需要注意里面的注释，关注 nextState 参数的用法。</p>
<h2 id="在-js-代码中获取-html-标签的属性"><a class="header" href="#在-js-代码中获取-html-标签的属性">在 js 代码中获取 html 标签的属性</a></h2>
<p>比如说，如果想获取 html 标签的 innerHTML 属性，做法如下：</p>
<p>通过原生 js 获取：</p>
<pre><code class="language-javascript">document.getElementById(&quot;myh3&quot;).innerHTML;
</code></pre>
<p>也可以通过 React 提供的 <code>refs</code> 获取：</p>
<pre><code class="language-javascript">this.refs.h3.innerHTML;
</code></pre>
<p>代码举例：</p>
<p>（3）/components/Counter.jsx：</p>
<pre><code class="language-java">import React from &quot;react&quot;;
// 注意： prop-types 包的职能跟单一，只提供了 一些常见的 数据类型，用于做类型校验
import ReactTypes from &quot;prop-types&quot;;

export default class Counter extends React.Component {
  constructor(props) {
    super(props);

    // 初始化组件，保存的是组件的私有数据
    this.state = {
      msg: &quot;ok&quot;,
      count: props.initcount // 把 父组件传递过来的 initcount 赋值给子组件 state 中的 count值。这样的话，就把 count 值改成了可读可写的 state 属性。因此，以后就能实现“点击 按钮 ，count 值 + 1”的需求了
    };
  }

  // 在 React 中，使用静态的 defaultProps 属性，来设置组件的默认属性值
  static defaultProps = {
    initcount: 0 // 如果外界没有传递 initcount，那么，自己初始化一个数值（比如0）
  };

  // 这是创建一个 静态的 propTypes 对象，在这个对象中，可以把 外界传递过来的属性，做类型校验
  static propTypes = {
    initcount: ReactTypes.number // 使用 prop-types 包，来定义 initcount 为 number 类型
  };

  render() {
    return (
      &lt;div&gt;
        &lt;div&gt;
          &lt;h3&gt;这是 Counter 计数器组件 &lt;/h3&gt;
          {/* 这里的 this 指向的是 Counter 组件的实例  */}
          &lt;input type=&quot;button&quot; value=&quot;+1&quot; id=&quot;btn&quot; onClick={this.myMethod} /&gt;
          &lt;h3 id=&quot;myh3&quot; ref=&quot;mymyh3&quot;&gt;
            当前的计数是：{this.state.count}
          &lt;/h3&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
    // 当 return 执行完毕后， 虚拟DOM创建好了，但是，还没有挂载到真正的页面中
  }

  // 点击事件的方法定义
  myMethod = () =&gt; {
    // 修改组件的state里面的值
    this.setState({
      count: this.state.count + 1
    });
  };

  // 判断组件是否需要更新
  shouldComponentUpdate(nextProps, nextState) {
    // 需求： 如果 state 中的 count 值是偶数，则 更新页面；如果 count 值 是奇数，则不更新页面。最终实现的的页面效果：2，4，6，8，10，12....

    // 经过打印测试发现：在 shouldComponentUpdate 中，通过 this.state.count 拿到的值，是上一次的旧数据，并不是当前最新的；
    // 解决办法：通过 shouldComponentUpdate 函数的第二个参数 nextState，可以拿到 最新的 state 数据。

    console.log(this.state.count + &quot; ---- &quot; + nextState.count);
    // return this.state.count % 2 === 0 ? true : false
    // return nextState.count % 2 === 0 ? true : false;
    return true;
  }

  // 组件将要更新。此时尚未更新，在进入这个 生命周期函数的时候，内存中的虚拟DOM是旧的，页面上的 DOM 元素 也是旧的
  componentWillUpdate() {
    // 经过打印分析发现：此时页面上的 DOM 节点，都是旧的，应该慎重操作，因为你可能操作的是旧DOM
    // console.log(document.getElementById('myh3').innerHTML)
    console.log(this.refs.mymyh3.innerHTML);
  }

  // 组件完成了更新。此时，state 中的数据、虚拟DOM、页面上的DOM，都是最新的，此时，你可以放心大胆的去操作页面了
  componentDidUpdate() {
    console.log(this.refs.mymyh3.innerHTML);
  }
}
</code></pre>
<p>上方代码中，componentWillUpdate() 和 componentDidUpdate() 方法里的代码，就是我们这一段要举的例子。</p>
<p>需要注意的是，<code>&lt;h3 id=&quot;myh3&quot; ref=&quot;mymyh3&quot;&gt;</code>这部分代码中，属性名只能小写，不能大写。</p>
<p>工程文件：</p>
<ul>
<li><a href="https://pan.baidu.com/s/1STNpgtmO23hE_cHIjNkBMA">2019-02-12-ReactDemo.zip</a></li>
</ul>
<h2 id="生命周期函数componentwillreceiveprops"><a class="header" href="#生命周期函数componentwillreceiveprops">生命周期函数：componentWillReceiveProps()</a></h2>
<p>当子组件第一次被渲染到页面上的时候，不会触发这个 函数。</p>
<p>只有当父组件中，通过 某些 事件，重新修改了 传递给 子组件的 props 数据之后，才会触发 componentWillReceiveProps。</p>
<p>代码举例：</p>
<p>（1）index.html:</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;!-- 容器，通过 React 渲染得到的 虚拟DOM，会呈现到这个位置 --&gt;
    &lt;div id=&quot;app&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>（2）main.js:（引入组件）</p>
<pre><code class="language-javascript">// JS打包入口文件
// 1. 导入包
import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom&quot;;

import MyParent from &quot;./components/TestReceiveProps.jsx&quot;;

// 使用 render 函数渲染 虚拟DOM
ReactDOM.render(
  &lt;div&gt;
    &lt;MyParent&gt;&lt;/MyParent&gt;
  &lt;/div&gt;,
  document.getElementById(&quot;app&quot;),
);
</code></pre>
<p>（3）TestReceiveProps.jsx：（组件的定义）</p>
<pre><code class="language-javascript">import React from &quot;react&quot;;

// 父组件
export default class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      msg: &quot;这是父组件中的 msg 消息&quot;,
    };
  }

  render() {
    return (
      &lt;div&gt;
        &lt;h1&gt;这是父组件&lt;/h1&gt;
        &lt;input
          type=&quot;button&quot;
          value=&quot;点击修改父组件的 MSG&quot;
          onClick={this.changeMsg}
        /&gt;
        &lt;hr /&gt;
        {/* 在父组件 Parent 中引用子组件 Son */}
        &lt;Son pmsg={this.state.msg} /&gt;
      &lt;/div&gt;
    );
  }

  changeMsg = () =&gt; {
    this.setState({
      msg: &quot;修改组件的msg为新的值&quot;,
    });
  };
}

// 子组件
class Son extends React.Component {
  constructor(props) {
    super(props);

    this.state = {};
  }

  render() {
    return (
      &lt;div&gt;
        &lt;h3&gt;这是子组件 --- {this.props.pmsg}&lt;/h3&gt;
      &lt;/div&gt;
    );
  }

  // 组件将要接收外界传递过来的新的 props 属性值
  // 当子组件第一次被渲染到页面上的时候，不会触发这个 函数；
  // 只有当 父组件中，通过 某些 事件，重新修改了 传递给 子组件的 props 数据之后，才会触发 componentWillReceiveProps
  componentWillReceiveProps(nextProps) {
    // console.log('被触发了！');
    // 注意： 在 componentWillReceiveProps 被触发的时候，如果我们使用 this.props 来获取属性值，这个属性值，不是最新的，是上一次的旧属性值
    // 如果想要获取最新的属性值，需要通过 componentWillReceiveProps 的参数列表来获取
    console.log(this.props.pmsg + &quot; ---- &quot; + nextProps.pmsg);
  }
}
</code></pre>
<p>上方代码中，我们在组件 Parent 中引入了子组件 Son。重点注意 componentWillReceiveProps()函数 的注释部分。</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../posts/react/react.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../posts/react/react_router.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../posts/react/react.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../posts/react/react_router.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>



        <script>
            window.playground_line_numbers = true;
        </script>

        <script>
            window.playground_copyable = true;
        </script>

        <script src="../../ace.js"></script>
        <script src="../../editor.js"></script>
        <script src="../../mode-rust.js"></script>
        <script src="../../theme-dawn.js"></script>
        <script src="../../theme-tomorrow_night.js"></script>

        <script src="../../elasticlunr.min.js"></script>
        <script src="../../mark.min.js"></script>
        <script src="../../searcher.js"></script>

        <script src="../../clipboard.min.js"></script>
        <script src="../../highlight.js"></script>
        <script src="../../book.js"></script>

        <!-- Custom JS scripts -->
        <script src="../../src/js/custom.js"></script>


    </div>
    </body>
</html>
